#include "main.h"
#include "string.h"
#define S2RI 0x01        //串口2接收中断请求标志位

unsigned char ucRtc[5] = {0, 0, 0, 0, 0};	//读取数据数据（月，日，时，分，秒）
bit g_hc05_receive_cover_flag = 0;
bit g_hc05_delaysend_flag = 0;
bit g_ESP8266_receive_flag = 0;
int g_esp8266_mode = 0;			            // esp8266 模式
int g_esp8266_data = 0;                     // esp8266 数据
unsigned char g_hc05_data = 0;              // HC05 数据
int g_zj_asr_v5_data = 0;   
sbit g_key = P2^7;                // 语音模块数据

/**
 * @brief 1ms timing
 * 
 */
void Timer0Init()		//1毫秒@12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x20;		//设置定时初值
	TH0 = 0xD1;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0 = 1;		//开启定时器0中断
	EA  = 1;		//开启总中断
}

/**
 * @brief 获取小程序发送的数据，将高八位存储为模式，第八位存储为数据位 
 * 
 */
void ESP8266_Supervisory_Control()
{
	int esp8266_Rec = 0;
	esp8266_Rec = ESP8266_Received();	
	//高八位是判断开关（1）、色温（2）、亮度（3）的标志位
	//低八位是对应的数值
	//没有返回值（esp8266_Rec = 0）
	g_esp8266_mode = esp8266_Rec / 256;
	g_esp8266_data = esp8266_Rec % 256;
}

/**
 * @brief OLED display 显示时分秒，光照强度，雷达情况
 * 
 * @param time 获取显示时间数据
 * @param light 获取显示光照强度
 * @param radar 获取雷达数据，显示是否有人
 */
void OLED_Display(unsigned char* time, unsigned char radar, int light, unsigned char color, unsigned char luminance)
{
	OLED_ShowNum(0,0,time[2]/16*10+time[2]%16,2,16);
	OLED_ShowChar(16, 1, ':', 8);
	OLED_ShowNum(23,0,time[3]/16*10+time[3]%16,2,16);
	OLED_ShowChar(39,1, ':', 8);
	OLED_ShowNum(46,0,time[4]/16*10+time[4]%16,2,16);
	
	if(radar==1)
	{
		OLED_ShowChinese(96,0,15);
		OLED_ShowChinese(112,0,17);
	}
	else
	{
		OLED_ShowChinese(96,0,16);
		OLED_ShowChinese(112,0,17);
	}

	OLED_ShowChinese(0,3,4);
	OLED_ShowChinese(16,3,5);
	OLED_ShowChar(32, 4, ':', 8);
	OLED_ShowNum(42,3,light,5,16);
	
	OLED_ShowChinese(0,6,8);
	OLED_ShowChinese(16,6,9);
	OLED_ShowChar(32, 7, ':', 8);
	OLED_ShowNum(39,6,color,3,16);
	OLED_ShowChinese(64,6,18);
	OLED_ShowChinese(80,6,7);
	OLED_ShowChar(96, 7, ':', 8);
	OLED_ShowNum(103,6,luminance,3,16);
	
}

void main(void)
{	
	const int color_temperature_max = 100;			 				 	// 亮度以及色温最大值
	float white_LED_PWM = 0, yellow_LED_PWM = 0; 					 	// 白色灯和黄色灯的PWM值
	float PWM_luminance_factor = 1; 								 	// 白色灯和黄色灯的亮度调节因子	
	int color_temperature = 50, luminance = 50; 					 	// 定义色温以及亮度
	unsigned char rd03_data = 0; 									 	// 雷达数据
	int lux = 0; 												   	 	// 光照强度数据
	int night_activity_status = 0, night_activity_last_status = 0; 	 	// 夜间是否有人状态, 本轮以及上一轮
	bit esp8266_switch_LED = 0, esp8266_last_switch_LED = 0; 		 	// esp8266 控制LED开关
	int esp8266_last_data = 0; 									     	// esp8266 上一轮数据（色温 / 亮度）
	unsigned char hc05_last_data = 0;     			 				 	// hc05（上一轮） 数据（色温 / 亮度）
	bit hc05_switch_LED = 0, hc05_last_switch_LED = 0; 	 				// HC05 控制LED开关
	unsigned char hc05_mode = 0;  								 	 	// hc05 控制模式
	unsigned char zj_asr_v5_last_data = 0; 		 				 		// 语音控制 LED （上一轮）数据
	bit zj_asr_v5_switch_LED = 0, zj_asr_v5_last_switch_LED = 0;		// 语音控制 LED 开关
	bit led_switch = 0; 											 	// 控制 LED 开关
	bit status_change_flag = 0; 						 	 			// 状态改变标志位

	ESP8266_Uart2_Init();
	ESP8266_Init();
	Timer0Init();
	OLED_Init();
	PWM_Init();
	HC05_init();
	Rtc_Init(ucRtc);
	OLED_Clear();

	ESP8266_Send_all(led_switch, color_temperature, luminance);

	while(1)
	{
		ESP8266_Supervisory_Control();
		lux = BH1750FVI_get_data();
		rd03_data = rd03_get_data();
		Read_Rtc(ucRtc);

		//判断按键是否按下
		if (g_key == 0)
		{
			delay_ms(20);
			while (g_key == 0);
			led_switch = ~led_switch;
		}

		// 判断夜间是否有人
		if ((rd03_data == 1) && (lux <= 10))
		{
			night_activity_status = 1;
		}
		else
		{
			night_activity_status = 0;
		}
		
		// 判断 esp8266 是否发送 LED 开关控制命令
		if (g_esp8266_mode == 1)
		{
			esp8266_switch_LED = g_esp8266_data;
		}

		// 判断 HC05 是否发送 LED 开关控制命令
		if ((g_hc05_data == 0) || (g_hc05_data == 1))
		{
			hc05_switch_LED = g_hc05_data;
		}

		// 判断 HC05 是否发送模式控制命令
		if ((g_hc05_data == 2) || (g_hc05_data == 3))
		{
			hc05_mode = g_hc05_data;
		}

		// 判断语音模块是否发送 LED 开关控制命令
		if ((g_zj_asr_v5_data == 0) || (g_zj_asr_v5_data == 1))	
		{
			zj_asr_v5_switch_LED = g_zj_asr_v5_data;
		}

		// 上升沿下降沿判断	
		if (night_activity_status != night_activity_last_status)
		{
			led_switch = 0;

			if (night_activity_status == 1)
			{
				led_switch = 1;
			}
			ESP8266_Send_all(led_switch, color_temperature, luminance);
		}
		if (esp8266_switch_LED != esp8266_last_switch_LED)
		{
			led_switch = 0;

			if (esp8266_switch_LED == 1)
			{
				led_switch = 1;
			}
			ESP8266_Send_all(led_switch, color_temperature, luminance);
		}
		if (hc05_switch_LED != hc05_last_switch_LED)
		{
			led_switch = 0;

			if (hc05_switch_LED == 1)
			{
				led_switch = 1;
			}
			ESP8266_Send_all(led_switch, color_temperature, luminance);
		}
		if (zj_asr_v5_switch_LED != zj_asr_v5_last_switch_LED)
		{
			led_switch = 0;

			if (zj_asr_v5_switch_LED == 1)
			{
				led_switch = 1;
			}
			ESP8266_Send_all(led_switch, color_temperature, luminance);
			OLED_Clear();
		}

		// 若 esp8266 发送更改色温 / 亮度数据，且数据不同于上一次，则更改对应数据
		if (g_esp8266_mode == 2)
		{
			color_temperature = g_esp8266_data;
		}
		else if (g_esp8266_mode == 3)
		{
			luminance = g_esp8266_data;
		}
		
		// 若 HC05 发送更改色温 / 亮度数据，且数据不同于上一次，则更改对应数据
		if ((hc05_mode == 2) && (g_hc05_data != hc05_last_data))
		{
			if (g_hc05_data != 2)
			{
				color_temperature = (int) (g_hc05_data/16*10+g_hc05_data%16);
				ESP8266_Send_all(led_switch, color_temperature, luminance);
			}
		}
		else if ((hc05_mode == 3) && (g_hc05_data != hc05_last_data))
		{
			if ((g_hc05_data != 0) && (g_hc05_data != 1) && (g_hc05_data != 2) && (g_hc05_data != 3))
			{
				luminance =  (int) (g_hc05_data/16*10+g_hc05_data%16);
				ESP8266_Send_all(led_switch, color_temperature, luminance);
			}
		}
		OLED_Display(ucRtc, rd03_data, lux, color_temperature, luminance);
		// 按照亮度计算 LED 亮度系数
		PWM_luminance_factor = luminance / 200.0;
		// 切换LED 开关状态，若开灯，则调整白色灯和黄色灯的亮度、色温数据
		if (led_switch == 1)
		{
			white_LED_PWM = (color_temperature_max - color_temperature) * PWM_luminance_factor * 2;
			yellow_LED_PWM = color_temperature * PWM_luminance_factor * 2;	
			CCAPM0 = 0x02;
			CCAPM1 = 0x02;
		}
		else
		{
			CCAPM0 = 0x00;
			CCAPM1 = 0x00;
			P35 = 0;
			P36 = 0;
		}

		// 控制白色灯和黄色灯的亮度
		Set_Pwm(0, 255 - (white_LED_PWM / 100 * 255));
		Set_Pwm(1, 255 - (yellow_LED_PWM / 100 * 255));

		// 刷新上一轮数据为本轮数据
		night_activity_last_status = night_activity_status;
		esp8266_last_switch_LED = esp8266_switch_LED;
		esp8266_last_data = g_esp8266_data;
		hc05_last_data = g_hc05_data;
		hc05_last_switch_LED = hc05_switch_LED;
		zj_asr_v5_last_data = g_zj_asr_v5_data;
		zj_asr_v5_last_switch_LED = zj_asr_v5_switch_LED;
	}
}

/**
 * @brief 串口中断（蓝牙接收数据)
 * 
 */
void HC05_get_data() interrupt 4	
{  
	if (RI==1)
	    {	  
			g_hc05_receive_cover_flag = 1;
			g_hc05_delaysend_flag = 1;
	  		g_hc05_data = SBUF;
			RI=0;  
		}	
}

/**
 * @brief timer1Routine
 * 
 */
void Timer0Routine() interrupt 1
{
	g_zj_asr_v5_data = ZJ_ASR_V5_get_date();
}

void ESP8266_Uart2_Isr() interrupt 8
{
	if(S2CON&S2RI)					//RI == 1 
	{
		S2CON&=~S2RI;				//RI = 0
		g_ESP8266_receive_flag = 1;
		ESP8266_Uart2_ReceiveByte();
	}
}

